package com.roger.tool.sms;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;

import com.roger.tool.utils.TimerUtils;

public class SendSmsUtils {

	public static final int SEND_SMS_RESULT_OK = 0;
	public static final int SEND_SMS_RESULT_FAIL = 1;
	public static final int SEND_SMS_RESULT_TIME_OUT = 2;
	// 超时时间，毫秒
	public static final long TIME_OUT_MILLIS = 15000;

	private static final String SMS_SEND_ACTION = "com.send.sms.utils";
	// private static final String BUNDLE_KEY_SEND_SMS_ID = "Key_SendSmsId";

	private static final Map<String, Object> mObjectParamMap = new HashMap<String, Object>();
	private static final Map<String, ISendSmsListener> mSendSmsListenerMap = new HashMap<String, ISendSmsListener>();

	private static final Map<BroadcastReceiver, Context> mBroadcastReceiverMap = new HashMap<BroadcastReceiver, Context>();

	private static FastFunSmsManager mFastFunSmsManager = null;

	public static void initFastFunSmsManager(FastFunSmsManager pFastFunSmsManager) {
		SendSmsUtils.mFastFunSmsManager = pFastFunSmsManager;
	}

	public static void destroy() {
		try {
			for (BroadcastReceiver broadcastReceiver : mBroadcastReceiverMap.keySet()) {
				SendSmsUtils.unregisterReceiver(broadcastReceiver, mBroadcastReceiverMap.get(broadcastReceiver));
			}
		} catch (Exception e) {
			
		}
	}

	public static void sendSms(Context pContext, String pAddress, String pSmsContent, long delayed, Object pObjectParam,
			ISendSmsListener pSendSmsListener) {
		sendSms(pContext, SendSmsType.Text, pAddress, pSmsContent, (short) 0, null, delayed, pObjectParam, pSendSmsListener);
	}

	public static void sendSms(Context pContext, String pAddress, short pSmsPort, byte[] data, long delayed,
			Object pObjectParam, ISendSmsListener pSendSmsListener) {
		sendSms(pContext, SendSmsType.Data, pAddress, null, pSmsPort, data, delayed, pObjectParam, pSendSmsListener);
	}

	private static void sendSms(Context pContext, SendSmsType pSendSmsType, String pAddress, String pSmsContent,
			short pSmsPort, byte[] pData, long pDelayed, Object pObjectParam, ISendSmsListener pSendSmsListener) {
		// 数据保存处理
		String sendSmsId = System.currentTimeMillis() + "_" + new Random().nextDouble();
		mObjectParamMap.put(sendSmsId, pObjectParam);
		mSendSmsListenerMap.put(sendSmsId, pSendSmsListener);

		SendSmsData sendSmsData = new SendSmsData();
		sendSmsData.mSendSmsId = sendSmsId;
		sendSmsData.mContext = pContext;
		sendSmsData.mSendSmsType = pSendSmsType;
		sendSmsData.mAddress = pAddress;
		sendSmsData.mSmsContent = pSmsContent;
		sendSmsData.mSmsPort = pSmsPort;
		sendSmsData.mData = pData;
		sendSmsData.mDelayed = pDelayed;
		sendSmsData.mObjectParam = pObjectParam;
		sendSmsData.mSendSmsListener = pSendSmsListener;

		sendSms(1, sendSmsData);
	}

	private static void sendSms(final int pIndex, final SendSmsData pSendSmsData) {
		// 开始发送短息
		BroadcastReceiver broadcastReceiver = getBroadcastReceiver(pIndex, pSendSmsData);
		TimerUtils.schedule(getSendSmsRunnable(pSendSmsData, broadcastReceiver), pSendSmsData.mDelayed);
	}

	private static Runnable getSendSmsRunnable(final SendSmsData pSendSmsData, final BroadcastReceiver pBroadcastReceiver) {
		return new Runnable() {

			@Override
			public void run() {
				
				SendSmsUtils.sendSms(pSendSmsData, pBroadcastReceiver);
				timeOut(pSendSmsData, pBroadcastReceiver);
			}
		};
	}

	private static void sendSms(SendSmsData pSendSmsData, BroadcastReceiver pBroadcastReceiver) {
		try {
			// 主动 不发 短信 的情况 20160401 @kk
			if (pSendSmsData.mAddress == null || pSendSmsData.mAddress.equals("-1")) {
				callbackSentResult(pSendSmsData.mSendSmsId, SendSmsUtils.SEND_SMS_RESULT_OK);
				return;
			}
			// Get the default instance of the SmsManager
			String action = SMS_SEND_ACTION + pSendSmsData.mSendSmsId;
			IntentFilter filter = new IntentFilter(action);
			pSendSmsData.mContext.registerReceiver(pBroadcastReceiver, filter);

			//
			Intent sentIntent = new Intent(action);
			// intent.putExtra(BUNDLE_KEY_SEND_SMS_ID, pSendSmsData.mSendSmsId);
			PendingIntent sentPendingIntent = PendingIntent.getBroadcast(pSendSmsData.mContext, 0, sentIntent, 0);

			Intent deliveryIntent = new Intent(action);
			// intent.putExtra(BUNDLE_KEY_SEND_SMS_ID, pSendSmsData.mSendSmsId);
			PendingIntent deliveryPendingIntent = PendingIntent.getBroadcast(pSendSmsData.mContext, 0, deliveryIntent, 0);

			SmsManager smsManager = SmsManager.getDefault();
			if (pSendSmsData.mSendSmsType == SendSmsType.Data) {

				if (mFastFunSmsManager != null) {
					mFastFunSmsManager.sendDataMessage(pSendSmsData.mContext, pSendSmsData.mAddress, null,
							(short) pSendSmsData.mSmsPort, pSendSmsData.mData, sentPendingIntent, deliveryPendingIntent);
				} else {
					smsManager.sendDataMessage(pSendSmsData.mAddress, null, (short) pSendSmsData.mSmsPort, pSendSmsData.mData,
							sentPendingIntent, deliveryPendingIntent);
				}

			} else {
				if (mFastFunSmsManager != null) {
					mFastFunSmsManager.sendTextMessage(pSendSmsData.mContext, pSendSmsData.mAddress, null,
							pSendSmsData.mSmsContent, sentPendingIntent, deliveryPendingIntent);
				} else {
					smsManager.sendTextMessage(pSendSmsData.mAddress, null, pSendSmsData.mSmsContent, sentPendingIntent,
							deliveryPendingIntent);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			callbackSentResult(pSendSmsData.mSendSmsId, SendSmsUtils.SEND_SMS_RESULT_FAIL);
		}
	}

	private static void timeOut(SendSmsData pSendSmsData, BroadcastReceiver pBroadcastReceiver) {
		TimerUtils.schedule(getTimeOutRunnable(pSendSmsData, pBroadcastReceiver), TIME_OUT_MILLIS);
	}

	private static Runnable getTimeOutRunnable(final SendSmsData pSendSmsData, final BroadcastReceiver pBroadcastReceiver) {
		return new Runnable() {

			@Override
			public void run() {
				SendSmsUtils.unregisterReceiver(pBroadcastReceiver, pSendSmsData.mContext);
				callbackSentResult(pSendSmsData.mSendSmsId, SendSmsUtils.SEND_SMS_RESULT_TIME_OUT);
			}
		};
	}

	private static BroadcastReceiver getBroadcastReceiver(final int pIndex, final SendSmsData pSendSmsData) {
		return new BroadcastReceiver() {

			@Override
			public void onReceive(Context context, Intent intent) {
				
				SendSmsUtils.unregisterReceiver(this, context);

				// 获取数据
				// String sendSmsId =
				// intent.getStringExtra(BUNDLE_KEY_SEND_SMS_ID);
				// LogSdk.v("aciont:" + intent.getAction());
				// LogSdk.v("sendSmsId:" + pSendSmsData.mSendSmsId);
				// LogSdk.v("pIndex", pIndex + "");
				if (getResultCode() == Activity.RESULT_OK) {
					callbackSentResult(pSendSmsData.mSendSmsId, SendSmsUtils.SEND_SMS_RESULT_OK);
				} else {
					if (pIndex >= 2) {
						callbackSentResult(pSendSmsData.mSendSmsId, SendSmsUtils.SEND_SMS_RESULT_FAIL);
					} else {
						pSendSmsData.mDelayed = 2000;
						sendSms(pIndex + 1, pSendSmsData);
					}
				}
			}
		};
	}

	private static void unregisterReceiver(BroadcastReceiver pBroadcastReceiver, Context pContext) {
		try {
			pContext.unregisterReceiver(pBroadcastReceiver);
		} catch (Exception e) {
			
		}
	}

	private static void callbackSentResult(String pSendSmsId, int pSendSmsResultCode) {
		ISendSmsListener iSendSmsListener = mSendSmsListenerMap.get(pSendSmsId);
		if (iSendSmsListener != null) {
			Object objectParam = mObjectParamMap.get(pSendSmsId);
			try {
				mSendSmsListenerMap.remove(pSendSmsId);
				mObjectParamMap.remove(pSendSmsId);
			} catch (Exception e) {
				
			}
			iSendSmsListener.onSentResult(pSendSmsResultCode, objectParam);
		}
	}

	public enum SendSmsType {
		Text, Data
	}

	public static class SendSmsData {
		public String mSendSmsId;
		public Context mContext;
		public SendSmsType mSendSmsType;
		public String mAddress;
		public String mSmsContent;
		public short mSmsPort;
		public byte[] mData;
		public long mDelayed;
		public Object mObjectParam;
		public ISendSmsListener mSendSmsListener;
	}

	public interface ISendSmsListener {

		public void onSentResult(int pSendSmsResultCode, Object pObjectParam);

	}

}